package service

import (
	"context"
	"errors"
	"fmt"
	"math/rand"
	smsv1 "webook/api/proto/gen/sms/v1"
	"webook/code/repository"
)

const codeTplId = "1877556"

//go:generate mockgen -source=./code.go -package=svcmocks -destination=mocks/code.mock.go CodeService
type CodeService interface {
	Send(ctx context.Context, biz, phone string) error
	Verify(ctx context.Context, biz, phone, inputCode string) (bool, error)
}

type SMSCodeService struct {
	sms  smsv1.SmsServiceClient
	repo repository.CodeRepository
}

func NewSMSCodeService(svc smsv1.SmsServiceClient, repo repository.CodeRepository) CodeService {
	return &SMSCodeService{
		sms:  svc,
		repo: repo,
	}
}

// Send 随机生成一个验证码并发送
func (s *SMSCodeService) Send(ctx context.Context, biz, phone string) error {
	code := s.generate()
	err := s.repo.Store(ctx, biz, phone, code)
	if err != nil {
		return err
	}

	_, err = s.sms.Send(ctx, &smsv1.SmsSendRequest{
		TplId:   codeTplId,
		Args:    []string{code},
		Numbers: []string{phone},
	})
	return err
}

// Verify 验证验证码的正确性
func (s *SMSCodeService) Verify(ctx context.Context, biz, phone, inputCode string) (bool, error) {
	ok, err := s.repo.Verify(ctx, biz, phone, inputCode)
	if errors.Is(err, repository.ErrCodeVerifyTooManyTimes) {
		return false, nil
	}
	return ok, err
}

func (s *SMSCodeService) generate() string {
	num := rand.Intn(999999)
	return fmt.Sprintf("%6d", num)
}
